package whf.framework.security.web;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import whf.framework.entity.AbstractEntity;
import whf.framework.entity.Entity;
import whf.framework.security.entity.Group;
import whf.framework.security.entity.Permission;
import whf.framework.security.entity.Role;
import whf.framework.security.entity.User;
import whf.framework.security.service.GroupService;
import whf.framework.security.service.GroupServiceImp;
import whf.framework.security.service.PermissionService;
import whf.framework.security.service.PermissionServiceImp;
import whf.framework.security.service.RoleService;
import whf.framework.security.service.RoleServiceImp;
import whf.framework.security.service.UserService;
import whf.framework.security.service.UserServiceImp;
import whf.framework.util.BeanInitialization;
import whf.framework.util.PermissionUtils;
import whf.framework.util.StringUtils;
import whf.framework.util.Utils;
import whf.framework.web.Constants;
import whf.framework.web.query.QueryBuilder;
import whf.framework.web.struts.WebData;
import whf.framework.web.struts.WebDispatchAction;
import whf.framework.web.struts.WebForward;

/**
 * @author wanghaifeng
 * @email king@126.com
 * @modify 2006-05-31
 */
public class RoleAction extends WebDispatchAction {

	//加入到组
	public WebForward prepareAddToGroup(AbstractEntity webEntity, WebData data) throws Exception {
		List<Group> groups = GroupServiceImp.getGroupService().findAll();
		data.setAttribute("groups", groups);
		long id = webEntity.getId();
		Role role = RoleServiceImp.getRoleService().findByPrimaryKey(id);
		role.setWebMethod("addToGroup");
		data.setAttribute(role);
		String selectedValues = "";
		for(Entity bo: groups){
			Group group = (Group)bo;
			if(group.contains(role)){
				if(selectedValues.equals("")){
					selectedValues=String.valueOf(group.getId());
				} else {
					selectedValues += ";"+String.valueOf(group.getId());
				}
			}
		}
		data.setAttribute("selectedValues", selectedValues);
		return data.forward("addToGroup");
	}
	
	public WebForward addToGroup(AbstractEntity webEntity, WebData data) throws Exception {
		long[] groupIds = data.getLongParameters("group", 0);
		List<Group> groups = Utils.newArrayList();
		GroupService groupService = GroupServiceImp.getGroupService();
		for(long groupId: groupIds){
			groups.add((Group)groupService.findByPrimaryKeyWithoutLazy(groupId));
		}
		RoleService roleService = RoleServiceImp.getRoleService();
		Role role = (Role)roleService.findByPrimaryKeyWithoutLazy(webEntity.getId());
		roleService.assignRoleGroups(role, groups);
		data.setAttribute(Constants.MESSAGE_THEN_CLOSE,"OK");
		return data.forward("addToGroup");
	}
	
	public WebForward preparePermissions(AbstractEntity webEntity, WebData data) throws Exception {
		long roleId = data.getLongParameter("roleId", 0);
		Role role = (Role)RoleServiceImp.getRoleService().findByPrimaryKeyWithoutLazy(roleId);
		data.setAttribute("selectedRole", role);
		role.setWebMethod("managePermissions");
		data.setAttribute(role);
		Set<Permission> perms = role.getPermissions();
		StringBuilder permIds = new StringBuilder();
		for(Permission perm: perms){
			if(permIds.length() == 0){
				permIds.append(perm.getId());
			} else {
				permIds.append(";").append(perm.getId());
			}
		}
		data.setAttribute("selectedPermIds", permIds.toString());
		String queryString = QueryBuilder.buildQueryString(data.getRequest());
		if(queryString == null) queryString = "";
		if(!StringUtils.isEmpty(queryString)) {
			queryString += " and ";
		}
		queryString += " exists (select p.id from " + Permission.class.getName() + " p where t.boClassName=p.target)";
		if(!data.getUserContext().isAdministrator()) {
			queryString += " and t.subModule !='framework'";
		}
		data.setAttribute("queryString", queryString);
		return data.forward("permissions");
	}
	
	public WebForward managePermissions(AbstractEntity webEntity, WebData data) throws Exception {
		long[] permIds = data.getLongParameters("perm", 0);
		long roleId = data.getLongParameter( "roleId", 0);
		PermissionService ps = PermissionServiceImp.getPermissionService();
		RoleService rs = RoleServiceImp.getRoleService();
		BeanInitialization.setInitializeProperties(new String[]{"permissions"});
		Role role = (Role)rs.findByPrimaryKeyWithoutLazy(roleId);
		Set<Permission> permissions = role.getPermissions();
		boolean changed = false;
		//
		String[] boClassNames = data.getParameterValues("boClassName");
		//移出没有被选中的，但是在级联授权的情况下，如果当前用户本就没有对当前perm操作的权限则不能移出
		for(Iterator<Permission> it = permissions.iterator(); it.hasNext(); ){
			Permission p = (Permission)it.next();
			String target = p.getTarget();
			boolean existsInFront = false;
			for(int i=0; boClassNames != null && i < boClassNames.length; i++){
				if(StringUtils.equals(target, boClassNames[i])){
					existsInFront = true;
					break;
				}
			}
			if(!existsInFront){
				continue;
			}
			if(!PermissionUtils.hasPermission(data.getUserContext(), p)){
				continue;
			}
			boolean found = false;
			if(permIds != null)
				for(long permId: permIds){
					if(p.getId() == permId){
						found = true;
						break;
					}
				}
			if(!found){
				it.remove();
				changed = true;
			}
		}
		if(permIds != null)
			for(long permId: permIds){
				if(permId == 0) continue;
				boolean found = false;
				for(Permission p: permissions){
					if(p.getId() == permId){
						found = true;
						break;
					}
				}
				if(!found){
					Permission perm = ps.findByPrimaryKey(permId);
					permissions.add(perm);
					changed = true;
				}
			}
		if(changed){
			rs.update(role);
		}
		data.addPageMessage("操作成功!");
		return preparePermissions(webEntity, data);
	}
	
	public WebForward roleUsers(AbstractEntity webEntity, WebData data) throws Exception {
		long roleId = data.getLongParameter( "roleId", 0);
		BeanInitialization.setInitializeProperties(new String[]{"users"});
		Role role = (Role)((RoleService)super.getService()).findByPrimaryKeyWithoutLazy(roleId);
		data.setAttribute("selectedRole", role);
		//
		List<User> selectedUsers = Utils.newArrayList();
		selectedUsers.addAll(role.getUsers());
		Collections.sort(selectedUsers, new Comparator<User>(){
			public int compare(User user1, User user2) {
				String name1 = user1.getName() == null?"": user1.getName();
				String name2 = user2.getName() == null?"": user2.getName();
				
				return name1.compareTo(name2);
			}
		});
		data.setAttribute("selectedUsers", selectedUsers);
		//
		List<User> users = UserServiceImp.getUserService().find("order by t.name");
		for(Iterator<User> it = users.iterator(); it.hasNext(); ){
			User user = (User)it.next();
			boolean selected = false;
			for(User u: selectedUsers){
				if(user.idEquals(u)){
					selected = true;
					break;
				}
			}
			if(selected){
				it.remove();
			}
		}
		data.setAttribute("availableUsers", users);
		//
		role.setWebMethod("manageUsers");
		data.setAttribute(role);
		return data.forward("roleUsers");
	}

	public WebForward manageUsers(AbstractEntity webEntity, WebData data) throws Exception {
		long roleId = data.getLongParameter( "roleId", 0);
		BeanInitialization.setInitializeProperties(new String[]{"users"});
		Role role = (Role)((RoleService)super.getService()).findByPrimaryKeyWithoutLazy(roleId);
		Set<User> users = role.getUsers();
		//
		long[] userIds = data.getLongParameters("selectedUsers", 0);
		for(Iterator<User> it = users.iterator(); it.hasNext(); ){
			User user = it.next();
			boolean selected = false;
			for(int i=0; userIds != null && i < userIds.length; i++){
				if(user.getId() == userIds[i]){
					selected = true;
					break;
				}
			}
			if(!selected){
				it.remove();
			}
		}
		UserService us = UserServiceImp.getUserService();
		for(int i=0; userIds != null && i < userIds.length; i++){
			if(userIds[i] == 0) continue;
			boolean found = false;
			for(Iterator<User> it = users.iterator(); it.hasNext(); ) {
				User user = it.next();
				if(user.getId() == userIds[i]){
					found = true;
					break;
				}
			}
			if(!found){
				users.add(us.findByPrimaryKey(userIds[i]));
			}
		}
		//
		((RoleService)super.getService()).update(role);
		return roleUsers(webEntity, data);
	}
	/**
	 * 将用户从角色中删除
	 * @param mapping
	 * @param webEntity
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public WebForward removeFromRole(AbstractEntity webEntity, WebData data) throws Exception {
		long roleId = data.getLongParameter( "roleId", 0);
		BeanInitialization.setInitializeProperties(new String[]{"users"});
		RoleService service = (RoleService)super.getService();
		Role role = (Role)service.findByPrimaryKeyWithoutLazy(roleId);
		data.setAttribute(role);
		
		Set<User> users = role.getUsers();
		long[] userIds = data.getLongParameters("id", 0);
		for(Iterator<User> it = users.iterator(); it.hasNext(); ){
			User user = (User)it.next();
			for(long userId: userIds){
				if(user.getId() == userId){
					it.remove();
					break;
				}
			}
		}
		service.update(role);
		
		return data.forward("roleUsers");
	}
} 